#include <math.h>
#include <allegro.h>

#define PI (atan(1)*4)

int main(void)
{
  float rotation = PI*0.25;
  float elevation = 1.1;
  float zoom = 50.0;
  float right_x, right_y;
  float front_x, front_y;
  float up_x, up_y; 

  float default_sprite_width = 1.0;
  float default_sprite_height = 2.0;

  float x, y, z, screen_x, screen_y;
  float sprite_width, sprite_height;

  PALETTE palette;
  BITMAP *buffer;
  BITMAP *image;

  if (allegro_init() != 0)
    return 1;
  install_timer();
  install_keyboard();

  set_color_depth(32);

  if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0) != 0) 
  {
   if (set_gfx_mode(GFX_SAFE, 320, 200, 0, 0) != 0)
    {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
      return 1;
    }
  }
  buffer = create_bitmap(SCREEN_W, SCREEN_H);

  image = load_bitmap("woman.bmp", palette);
  
  while (!key[KEY_ESC])
  {
    clear_bitmap(buffer);

    if (key[KEY_4_PAD]) rotation += 0.01;
    if (key[KEY_6_PAD]) rotation -= 0.01;    
    if (key[KEY_8_PAD]) elevation += 0.01;
    if (key[KEY_2_PAD]) elevation -= 0.01;    
    if (key[KEY_9_PAD]) zoom *= 1.01;    
    if (key[KEY_3_PAD]) zoom *= 0.99;

    /* precalculated vectors */
    right_x = cos(rotation) * zoom;
    right_y = sin(rotation) * cos(elevation) * zoom;
    front_x = -sin(rotation) * zoom;
    front_y = cos(rotation) * cos(elevation) * zoom;
    up_x = 0.0 * zoom;
    up_y = sin(elevation) * zoom;

    sprite_width = default_sprite_width * zoom;
    sprite_height = default_sprite_height * zoom;

    /* painting the ground */
    z = 0.0;
    for (x=-5.0; x<=5.0; x+=1.0)
    {
      for (y=-5.0; y<=5.0; y+=1.0)
      {
        screen_x = x * right_x + y * front_x + z * up_x;
        screen_y = x * right_y + y * front_y + z * up_y; 

        putpixel(buffer, 
                (int)floor(screen_x + SCREEN_W * 0.5), 
                (int)floor(screen_y + SCREEN_H * 0.5),
                makecol(255, 255, 255));

      }
    }

    /* painting the sprite */
    x=3.0;
    y=-3.0;
    z=0.0;

    screen_x = x * right_x + y * front_x + z * up_x;
    screen_y = x * right_y + y * front_y + z * up_y; 

    screen_x -= (sprite_width * 0.5);
    screen_y -= sprite_height;
    BITMAP *stretched;
    stretch_sprite(buffer, image,
         (int)floor(screen_x + SCREEN_W * 0.5), (int)floor(screen_y + SCREEN_H * 0.5), 
         sprite_width, sprite_height);


    textprintf_ex(buffer, font, 10, 10, makecol(255, 255, 255), -1, 
                  "rotation.: % 06.2f", rotation);
    textprintf_ex(buffer, font, 10, 20, makecol(255, 255, 255), -1, 
                  "elevation: % 06.2f", elevation);

    blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
    yield_timeslice();
  }

  destroy_bitmap(buffer);
  return 0;
}

END_OF_MAIN();

